<?php
/**
 *（Logic） 回写Amazon物流数据
 */
namespace App\Logic\Amazon\Api;

use App\Models\Basics\AmazonAccount;
use App\Models\Basics\AmazonCountry;
use App\Models\CustomerDelivery\CustomerDeliveryDetail;
use App\Models\CustomerDelivery\CustomerLogs;
use App\Models\CustomerDelivery\CustomerOrder;
use SellingPartnerApi\Api\FbaOutboundV20200701Api as FbaCustomerOutboundApi;
use SellingPartnerApi\Model\FbaOutboundV20200701\Address;
use SellingPartnerApi\Model\FbaOutboundV20200701\CreateFulfillmentOrderItem;
use SellingPartnerApi\Model\FbaOutboundV20200701\CreateFulfillmentOrderRequest;
use SellingPartnerApi\Model\FbaOutboundV20200701\FulfillmentShipment;
class CustomerOutbound
{

    public static function apiCreateFulfillmentOrder($customerDeliveryOrder,$deliveryOrderNo,$platAccountId){

        if(!$customerDeliveryOrder) return false;
        if(!$customerDeliveryOrder->detail) return false;
        if(!$customerDeliveryOrder->receiver) return false;
        if(!$deliveryOrderNo && !$platAccountId) return false;

        $marketplaceId = AmazonCountry::getValueByCountryId($customerDeliveryOrder->country_id, 'marketplace_id');
        if(!$marketplaceId) return false;

        $account = AmazonAccount::query()->find($platAccountId);
        if (!$account) return false;
        $requiredConfig = RequiredConfig::getInit();
        $config = $requiredConfig->configuration($account->refresh_token, $account->aws_region);
        $apiInstance = new FbaCustomerOutboundApi($config);

        //验证订单是否已存在于Amazon平台(多渠道)
        $fulfillmentOrder = self::_getFulfillmentOrder($apiInstance,$deliveryOrderNo);
        if ($fulfillmentOrder) {
            $sellerFulfillmentOrderId = $fulfillmentOrder->getFulfillmentOrder()->getSellerFulfillmentOrderId();
            $fulfillmentShipments = $fulfillmentOrder->getFulfillmentShipments();
            if($fulfillmentShipments){
                foreach ($fulfillmentShipments as $fulfillmentShipment){
                    //更新订单状态以及物流信息
                    self::_extractFulfillmentOrder($fulfillmentShipment,$sellerFulfillmentOrderId);
                }
            }
            return true;
        }

        //明细
        $customerDeliveryDetails = CustomerDeliveryDetail::query()
            ->where('delivery_order_no', $deliveryOrderNo)
            ->where('account_id', $platAccountId)
            ->get();
        $orderItem = [];
        if ($customerDeliveryDetails->isNotEmpty()) {
            foreach ($customerDeliveryDetails as $key => $deliveryDetails){
                if ($deliveryDetails->status != 3) continue; //待发货

                $orderItem[] = new CreateFulfillmentOrderItem([
                    'seller_sku' => $deliveryDetails->seller_sku,
                    'seller_fulfillment_order_item_id' => $deliveryOrderNo.'_'.$platAccountId.'_'.$key, //订单明细ID (实际发货订单号+账号ID+数组键名)
                    'quantity' => $deliveryDetails->apply_num,
                ]);
            }
        }
        if(!$orderItem) return false;

        //地址
        $address1 = $customerDeliveryOrder->receiver->city . $customerDeliveryOrder->receiver->address ?? '';
        $address2 = ''; //(地址长度限制：20字符，地址1超过20字符，超过的部分，要拆解到地址2)
        if (strlen($address1) > 20) {
            $str = $address1;
            $address1 = mb_substr($str, 0, 20, 'UTF-8');
            $address2 = mb_substr($str, 20, null, 'UTF-8');
        }
        $postcode = $customerDeliveryOrder->receiver->postcode ? formatPostcode($customerDeliveryOrder->receiver->postcode) : '';
        $orderAddress = new Address([
            'name' => $customerDeliveryOrder->receiver->receiver ?? '',
            'address_line1' => $address1,
            'address_line2' => $address2,
            'state_or_region' => $customerDeliveryOrder->receiver->state ?? '',
            'city' => $customerDeliveryOrder->receiver->city ?? '',
            'district_or_county' => $customerDeliveryOrder->receiver->state ?? '',
            'country_code' => $customerDeliveryOrder->receiver->country ?? '',
            'postal_code' => $postcode,
            'phone' => $customerDeliveryOrder->receiver->phone ?? '',
        ]);

        //订单参数
        $remark = 'Thank you for your order!';
        if ($customerDeliveryOrder->plat_id == 3) {
            $remark = 'ご注文いただきありがとうございます'; //JP订单备注
        }
        $body = new CreateFulfillmentOrderRequest([
            'marketplace_id' => $marketplaceId,
            'seller_fulfillment_order_id' => $deliveryOrderNo,
            'displayable_order_id' => $deliveryOrderNo,
            'displayable_order_date' => getDateFormat($customerDeliveryOrder->order_at),
            'displayable_order_comment' => $remark,
            'shipping_speed_category' => 'Standard',
            'items' => $orderItem,
            'destination_address' => $orderAddress,
        ]);

        try{
            $res = $apiInstance->createFulfillmentOrder($body);
            if ($res->getErrors() != 'null'){
                return false;
            }

            return true;
        }catch (\Exception $e){
            report($e);

            CustomerLogs::logs(CustomerLogs::$overseasInboundOrder,'FBA多渠道发货(上传平台订单)',$e->getMessage(),$deliveryOrderNo);
            return false;
        }

    }

    /**
     * 依据账号、单号,获取Amazon多渠道订单
     * @param $accountId
     * @param $seller_fulfillment_order_id
     * @return bool
     * @throws \Exception
     */
    public static function getFulfillmentOrder($accountId,$seller_fulfillment_order_id){
        if(!$accountId) return false;
        if(!$seller_fulfillment_order_id) return false;
        $account = AmazonAccount::query()->find($accountId);
        if(!$account) return false;

        $requiredConfig = RequiredConfig::getInit();
        $config = $requiredConfig->configuration($account->refresh_token, $account->aws_region);

        $apiInstance = new FbaCustomerOutboundApi($config);
        $fulfillmentOrder = self::_getFulfillmentOrder($apiInstance,$seller_fulfillment_order_id);
        if($fulfillmentOrder){
            return true;
        }

        return false;
    }

    /**
     * Returns a fulfillment order
     * @param $config
     * @param $account
     * @param $seller_fulfillment_order_id
     * @return bool
     */
    public static function apiGetFulfillmentOrder($config,$account,$seller_fulfillment_order_id){
        if(!$account)return false;
        if(!$seller_fulfillment_order_id)return false;
        $apiInstance = new FbaCustomerOutboundApi($config);
        $fulfillmentOrder = self::_getFulfillmentOrder($apiInstance,$seller_fulfillment_order_id);
        if($fulfillmentOrder){
            $fulfillmentShipments = $fulfillmentOrder->getFulfillmentShipments();
            if($fulfillmentShipments){
                foreach ($fulfillmentShipments as $fulfillmentShipment){
                    self::_extractFulfillmentOrder($fulfillmentShipment,$seller_fulfillment_order_id);
                }
            }
        }
        return true;
    }

    private static function _extractFulfillmentOrder(FulfillmentShipment $fulfillmentShipment,$seller_fulfillment_order_id){
        //try{
        //    DB::beginTransaction();
            $amazonShipmentId = $fulfillmentShipment->getAmazonShipmentId(); //发货ID
            $deliveryAt = $fulfillmentShipment->getShippingDate(); //发货时间
            if($amazonShipmentId){
                $fulfillmentShipmentPackages = $fulfillmentShipment->getFulfillmentShipmentPackage();
                if($fulfillmentShipmentPackages){
                    $trackingNumber = ''; //物流追踪号
                    $carrierCode = '';    //物流公司
                    $arrivalDate = null; //预计到货时间(送达时间)
                    foreach ($fulfillmentShipmentPackages as $fulfillmentShipmentPackage){
                        $trackingNumber = $fulfillmentShipmentPackage->getTrackingNumber();
                        $carrierCode = $fulfillmentShipmentPackage->getCarrierCode();
                        if ($fulfillmentShipmentPackage->getEstimatedArrivalDate()) {
                            $arrivalDate = date('Y-m-d', strtotime($fulfillmentShipmentPackage->getEstimatedArrivalDate()));
                        }
                        if($trackingNumber && $carrierCode)break;
                    }

                    if($trackingNumber){
                        $fulfillmentShipmentItem = $fulfillmentShipment->getFulfillmentShipmentItem();
                        if($fulfillmentShipmentItem){
                            $sellerSkus = [];
                            foreach ($fulfillmentShipmentItem as $itemKey => $_fulfillmentShipmentItem){
                                $sellerSkus[$itemKey]['seller_sku'] = $_fulfillmentShipmentItem->getSellerSku();
                                $sellerSkus[$itemKey]['quantity'] = $_fulfillmentShipmentItem->getQuantity() ?? 0;
                            }
                            if ($sellerSkus) {
                                foreach ($sellerSkus as $index => $sku){
                                    //发货明细(物流状态同步)
                                    CustomerDeliveryDetail::query()
                                        ->where('delivery_order_no',$seller_fulfillment_order_id)
                                        ->where('seller_sku',$sku['seller_sku'])
                                        ->update([
                                            'tracking_no' => $trackingNumber, //物流追踪号
                                            'logistics_type' => $carrierCode, //物流公司
                                            'delivered_at' => $deliveryAt, //erp发货时间
                                            'shipping_date' => $arrivalDate, //Amazon配送日期(送达时间)
                                            'sync_status' => 1, //物流同步状态 (0:未同步 1:已同步)
                                            'status' => 5, //已发货
                                            'ship_num' => $sku['quantity'] //发货数量
                                        ]);
                                }

                                //验证,更新发货订单(发货单状态、订单同步状态)
                                $deliveryDetailStatusArr = CustomerDeliveryDetail::query()
                                    ->where('delivery_order_no',$seller_fulfillment_order_id)
                                    ->pluck('status')
                                    ->toArray();
                                if($deliveryDetailStatusArr) {
                                    $status = CustomerDeliveryDetail::extractStatus($deliveryDetailStatusArr); //订单状态
                                    $customerDeliveryDetail = CustomerDeliveryDetail::query()
                                        ->where('delivery_order_no',$seller_fulfillment_order_id)
                                        ->first();
                                    if ($customerDeliveryDetail->delivery) {
                                        $customerDeliveryDetail->delivery->update([
                                            'status' => $status,  //发货单状态
                                            'plat_sync_status' => 2, //已上传至平台
                                            'plat_sync_at' => date('Y-m-d H:i:s', time())
                                        ]);
                                    }

                                    //更新客户订单
                                    $customerOrder = CustomerOrder::query()
                                        ->where('order_no',$customerDeliveryDetail->order_no)
                                        ->first();
                                    if ($customerOrder) {
                                        //更新客户订单明细
                                        if ($customerOrder->detail) {
                                            $customerOrder->detail()->update([
                                                'sync_status' => CustomerOrder::SYNC_YES //第三方平台(物流)信息已同步
                                            ]);

                                            $customerOrder->sync_status = CustomerOrder::SYNC_YES; //第三方平台(物流)信息已同步
                                            $customerOrder->save();
                                        }
                                    }
                                }
                            }

                        }
                    }
                }
            }
        //    DB::commit();
        //}catch (\Exception $e){
        //    DB::rollBack();
        //    report($e);
        //}
    }

    public static function _getFulfillmentOrder(FbaCustomerOutboundApi $apiInstance,$seller_fulfillment_order_id){
        try{
            $result = $apiInstance->getFulfillmentOrder($seller_fulfillment_order_id);
        }catch (\Exception $e){
            report($e);
            return null;
        }
        return $result->getPayload();
    }
}
